import _ from 'lodash';
import { Agent } from '../entities/agent';
import { EntityRepository, Repository } from 'typeorm';
import { AgentPageQuery } from '../dtos';
import buildPaginator from 'pagination-apis';
export interface IAgentRepository {
  findByIdentity(identity: string): Promise<Agent | undefined>;
  findByProduct(product: string): Promise<Agent[]>;
  findByProductAndStatus(product: string, status: string): Promise<Agent[]>;
  findByIdentitiesAndStatus(identities: string[], status: string): Promise<Agent[]>;
  findForPage(pageQuery: AgentPageQuery): Promise<any>;
}

@EntityRepository(Agent)
export class AgentRepository extends Repository<Agent> implements IAgentRepository {

  async findByIdentity(identity: string): Promise<Agent | undefined> {
    return await this.findOne({ where: { identity } });
  }

  async findByProductAndStatus(product: string, status: string) {
    return await this.createQueryBuilder('agents_alias')
      .where(':productName = ANY (agents_alias.products) and status=:status', { productName: product, status })
      .getMany();
  }

  /**
   * @description Like SQL: select * from agent where 'matlab'= ANY(products);
   * @link https://stackoverflow.com/a/63860654/14927941
   */
  async findByProduct(product: string): Promise<Agent[]> {
    return await this.createQueryBuilder('agents_alias')
      .where(':productName = ANY (agents_alias.products)', { productName: product })
      .getMany();
  }

  async findByIdentitiesAndStatus(identities: string[], status: string) {
    return await this.createQueryBuilder()
      .where('identity IN (:...identities) and status=:status', { identities, status })
      .getMany();
  }

  async findForPage(pageQuery: AgentPageQuery): Promise<any> {
    const { skip, limit, paginate } = buildPaginator({ page: pageQuery.currentPage || 1, limit: pageQuery.pageSize || 10 });
    let query = this.createQueryBuilder('agentPage').where('1=1');
    if (pageQuery.identity) {
      query.andWhere('identity like :identity', { identity: '%' + pageQuery.identity + '%' });
    }
    if (pageQuery.product) {
      query.andWhere(':product = ANY(products)', { product: pageQuery.product });
    }
    // console.log(query.getSql());
    const [data, total] = await query.addOrderBy('id', 'DESC')
      .skip(skip)
      .take(limit)
      .getManyAndCount();
    return paginate(data, total);
  }


}